﻿//1814. 统计一个数组中好对子的数目
//
//给你一个数组 nums ，数组中只包含非负整数。定义 rev(x) 的值为将整数 x 各个数字位反转得到的结果。比方说 rev(123) = 321 ， rev(120) = 21 。我们称满足下面条件的下标对(i, j) 是 好的 ：
//
//0 <= i < j < nums.length
//nums[i] + rev(nums[j]) == nums[j] + rev(nums[i])
//请你返回好下标对的数目。由于结果可能会很大，请将结果对 109 + 7 取余 后返回。
//
//示例 1：
//
//输入：nums = [42, 11, 1, 97]
//输出：2
//解释：两个坐标对为：
//- (0, 3)：42 + rev(97) = 42 + 79 = 121, 97 + rev(42) = 97 + 24 = 121 。
//- (1, 2)：11 + rev(1) = 11 + 1 = 12, 1 + rev(11) = 1 + 11 = 12 。

class Solution {
#define MOD 1000000007
    using ll = long long;
public:
    int countNicePairs(vector<int>& nums) {
        ll ret = 0;
        int n = nums.size();
        unordered_map<ll, ll> vartotime;
        for (int i = 0; i < n; ++i) {
            ll val = nums[i], tmp = 0;
            while (val) {
                tmp = tmp * 10 + val % 10;
                val /= 10;
            }

            ll curval = nums[i] - tmp;
            ret = (vartotime[curval] % MOD + ret % MOD) % MOD;
            vartotime[curval] = (vartotime[curval] % MOD + 1) % MOD;
        }
        return ret % MOD;
    }
};


//1806. 还原排列的最少操作步数
//
//给你一个偶数 n​​​​​​ ，已知存在一个长度为 n 的排列 perm ，其中 perm[i] == i​（下标 从 0 开始 计数）。
//
//一步操作中，你将创建一个新数组 arr ，对于每个 i ：
//
//如果 i % 2 == 0 ，那么 arr[i] = perm[i / 2]
//如果 i % 2 == 1 ，那么 arr[i] = perm[n / 2 + (i - 1) / 2]
//然后将 arr​​ 赋值​​给 perm 。
//
//要想使 perm 回到排列初始值，至少需要执行多少步操作？返回最小的 非零 操作步数。
//
//
//示例 1：
//
//输入：n = 2
//输出：1
//解释：最初，perm = [0, 1]
//第 1 步操作后，perm = [0, 1]
//所以，仅需执行 1 步操作

class Solution {
public:
    int reinitializePermutation(int n) {
        // [0, 1, 2, 3, 4, 5]
        // [0, 3, 1, 4, 2, 5]
        // [0, 4, 3, 2, 1, 5]
        // [0, 2, 4, 1, 3, 5]
        // [0, 1, 2, 3, 4, 5]
        int ret = 0;
        int cur = 1;
        do {
            cur = (cur * 2) % (n - 1);
            ret++;
        } while (cur != 1 && cur != 0);
        return ret;
    }
};